package controllers

import (
	"database/sql"
	"fmt"
	"mybeego/constants"
	"strconv"
	"sync"

	beego "github.com/beego/beego/v2/server/web"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

type MainController struct {
	BaseController
}

// 连接池配置
type dbConfig struct {
	User      string
	Password  string
	Host      string
	Port      string
	Name      string
	Charset   string
	AliasName string
	MaxOpen   int
	MaxIdle   int
}

var (
	myDb     *sqlx.DB
	mainOnce sync.Once
	//mainCfg  = dbConfig{
	//	User:      "root",
	//	Password:  "123456",
	//	Host:      "127.0.0.1",
	//	Port:      "3307",
	//	Name:      "cashew",
	//	Charset:   "utf8mb4",
	//	AliasName: "mysql",
	//	MaxOpen:   100, // 根据实际负载调整
	//	MaxIdle:   20,  // 建议MaxIdle <= MaxOpen/2
	//}
)

// 从配置文件中加载数据库配置
func loadDBConfig() (dbConfig, error) {

	dbUser, _ := beego.AppConfig.String("database::user")
	dbPassword, _ := beego.AppConfig.String("database::password")
	dbHost := beego.AppConfig.DefaultString("database::host", "127.0.0.1")
	dbPort := beego.AppConfig.DefaultString("database::port", "3306")
	dbName, _ := beego.AppConfig.String("database::name")
	dbCharset := beego.AppConfig.DefaultString("database::charset", "utf8mb4")

	cfg := dbConfig{
		User:     dbUser,
		Password: dbPassword,
		Host:     dbHost,
		Port:     dbPort,
		Name:     dbName,
		Charset:  dbCharset,
	}

	fmt.Printf("dbConfig: %+v \n", cfg)

	// 转换数字类型的配置
	maxOpen, _ := strconv.Atoi(beego.AppConfig.DefaultString("database::max_open", "100"))
	cfg.MaxOpen = maxOpen

	maxIdle, _ := strconv.Atoi(beego.AppConfig.DefaultString("database::max_idle", "20"))
	cfg.MaxIdle = maxIdle

	// 验证必要配置
	if cfg.User == "" || cfg.Password == "" || cfg.Name == "" {
		return dbConfig{}, fmt.Errorf("数据库配置不完整")
	}

	return cfg, nil
}

func initDB() error {
	// 从配置文件加载配置
	cfg, err := loadDBConfig()
	if err != nil {
		return fmt.Errorf("加载数据库配置失败: %w", err)
	}
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=true",
		cfg.User,
		cfg.Password,
		cfg.Host,
		cfg.Port,
		cfg.Name,
		cfg.Charset,
	)

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("sql.Open failed: %w", err)
	}

	if err = db.Ping(); err != nil {
		return fmt.Errorf("db.Ping failed: %w", err)
	}

	db.SetMaxOpenConns(cfg.MaxOpen)
	db.SetMaxIdleConns(cfg.MaxIdle)

	myDb = sqlx.NewDb(db, "mysql")

	return nil
}

// 安全的数据库访问方法
func getDB() (*sqlx.DB, error) {
	var err error
	mainOnce.Do(func() {
		err = initDB() // 延迟初始化
	})

	if err != nil {
		return nil, err
	}

	return myDb, nil
}

func (c *MainController) Get() {

	// 安全获取数据库连接
	db, err := getDB()
	if err != nil {
		c.Result(1001, map[string]interface{}{
			"msg": "数据库连接失败: " + err.Error(),
		})
		return
	}

	rows, err := db.Query("select * from anchor_info where status")
	if err != nil {
		c.Result(1002, map[string]interface{}{
			"msg": "查询失败: " + err.Error(),
		})
		return
	}
	defer rows.Close()

	var result []map[string]interface{}
	columns, _ := rows.Columns()
	for rows.Next() {
		values := make([]interface{}, len(columns))
		pointers := make([]interface{}, len(columns))
		for i := range values {
			pointers[i] = &values[i]
		}

		if err = rows.Scan(pointers...); err != nil {
			c.Result(1003, map[string]interface{}{"msg": fmt.Sprintf("扫描行失败: %v", err)})
			return
		}

		entry := make(map[string]interface{})
		for i, col := range columns {
			// 关键修改：转换 []byte 到 string
			if b, ok := values[i].([]byte); ok {
				entry[col] = string(b)
			} else {
				entry[col] = values[i]
			}
		}
		result = append(result, entry)
	}

	fmt.Println(result)

	res := make(map[string]interface{})
	res["msg"] = "你好啊! 这是 mybeego4 !"
	res["data"] = result
	c.Result(constants.SUCCESS, res)
	return
}
